<template>
  <div class="table-search-wrapper">
    <div
      class="form-wrapper"
      v-if="handleFormItemInline.length && searchBtn"
      :class="{ panel: pageNameDisplay }"
    >
      <div v-if="pageNameDisplay" class="panel-header">
        <span class="header-title">{{ pageName }}查询</span>
      </div>
      <div class="form-content">
        <i-form
          size="small"
          ref="form"
          :layout-span="layoutSpan"
          :breakpoint="breakpoint"
          :inline="true"
          :label-width="labelWidth"
          :items="
            handleFormItemInline.length > 6
              ? !fold
                ? handleFormItemInline
                : [
                    handleFormItemInline[0],
                    handleFormItemInline[1],
                    handleFormItemInline[2],
                    handleFormItemInline[3],
                    handleFormItemInline[4],
                    handleFormItemInline[5],
                  ]
              : handleFormItemInline
          "
          :model="form"
          class="iform"
          :rules="rules"
        >
          <template v-for="formItem in handleFormItemInline">
            <slot :name="formItem.slot" :slot="formItem.slot" />
            <slot v-if="filterFormComponents(formItem.type)">
              <el-form-item>
                <component :is="formItem.type" v-bind="formItem"> </component>
              </el-form-item>
            </slot>
          </template>
        </i-form>
        <div class="btn-wrapper">
          <div
            class="dash-control"
            v-show="handleFormItemInline.length > 6"
            @click="fold = !fold"
          >
            <i
              :class="[
                'el-collapse-item__arrow el-icon-arrow-down',
                fold ? '' : 'unfold',
              ]"
            />
            <span class="btn-text">{{ fold ? '展开' : '收起' }}</span>
          </div>
          <el-button
            size="small"
            type="primary"
            v-if="searchBtn"
            @click="handleTableData"
            >查询</el-button
          >
          <el-button size="small" @click="reset" v-if="resetBtnDisplay"
            >重置</el-button
          >
        </div>
      </div>
    </div>

    <div
      class="table-dash"
      v-if="handleColumns.length"
      :class="{ panel: pageNameDisplay }"
    >
      <slot name="tableSearchHeader">
        <div
          style="
            display: flex;
            justify-content: space-between;
            align-items: center;
          "
        >
          <div v-if="pageNameDisplay" class="panel-header header-flex">
            <span class="header-title"> {{ pageName }}列表</span>
            <div
              class="search-result-count"
              v-if="paginationDisplay && !paginationSlotDisplay"
            >
              当前搜索结果<strong>{{ tableData.totalCount || 0 }}</strong
              >条
            </div>
          </div>
          <div
            v-if="pageNameDisplay"
            class="search-header"
            :class="{
              'search-header': true,
              'reset-style': !paginationDisplay && paginationSlotDisplay,
            }"
          >
            <div class="btn-group-block">
              <div
                class="btn-group"
                :key="btn.label"
                v-for="btn in tableBtns.filter((btn) => {
                  return tableBtnsFilter(btn)
                })"
              >
                <a
                  v-if="btn.isDownload"
                  :href="btn.href"
                  :download="btn.fileName || '模板'"
                >
                  {{ btn.label }}
                </a>
                <ExportButton
                  v-else-if="btn.isExport"
                  :start-download="btn.startDownload"
                  size="small"
                />
                <el-button
                  v-else
                  :class="
                    typeof btn.class === 'function' ? btn.class() : btn.class
                  "
                  :disabled="
                    typeof btn.disabled === 'function'
                      ? btn.disabled()
                      : btn.disabled
                  "
                  @click="btn.click"
                  small
                  :type="btn.type ? btn.type : 'primary'"
                  :icon="btn.icon"
                  size="small"
                >
                  {{ btn.label }}
                </el-button>
              </div>
            </div>
          </div>
        </div>
      </slot>
      <i-table
        v-loading="loading"
        class="table-wrapper"
        ref="iTable"
        v-bind="$attrs"
        v-on="$listeners"
        :data="tableData.list"
        :columns="handleColumns"
        :pagination="pagination"
        :total="tableData.totalCount"
        layout="total, sizes, prev, pager, next, jumper"
        @pagination-change="handlePageChange"
        @selection-change="handleSelectionChange"
      >
        <template v-for="column in columns">
          <slot :name="column.slot" :slot="column.slot" />
        </template>
        <template>
          <slot name="operationBtns" />
        </template>
        <el-table-column label="操作" slot="operationBtns" width="300px">
          <template #default="{ row }">
            <template v-if="btnsFilter(row).length <= 2">
              <template v-for="(button, index) in btnsFilter(row)">
                <ExportButton
                  v-if="button.isExport"
                  :key="
                    index + pagination
                      ? pagination.currentPage + pagination.pageSize
                      : 0
                  "
                  :start-download="
                    (callback) => {
                      btnsFilter(row)[0].startDownload(callback, row)
                    }
                  "
                  class="table-button-green"
                  :inTable="true"
                />
                <el-button
                  v-else
                  :key="index"
                  v-bind="button"
                  :class="
                    typeof button.class === 'function'
                      ? button.class(row)
                      : button.class
                      ? button.class
                      : index === 0
                      ? 'table-button-green'
                      : 'table-button-blue'
                  "
                  type="text"
                  :disabled="
                    typeof button.disabled === 'function'
                      ? button.disabled(row)
                      : button.disabled
                  "
                  :loading="
                    typeof button.loading === 'function'
                      ? button.loading(row)
                      : button.loading
                  "
                  @click="button.click(row)"
                >
                  {{
                    typeof button.label === 'function'
                      ? button.label(row)
                      : button.label
                  }}
                </el-button>
              </template>
            </template>
            <template v-else>
              <!-- 暂时解决方案，只有第一个是导出类型才会渲染为导出按钮 -->
              <ExportButton
                v-if="btnsFilter(row)[0].isExport"
                :key="
                  pagination ? pagination.currentPage + pagination.pageSize : 0
                "
                :start-download="
                  (callback) => {
                    btnsFilter(row)[0].startDownload(callback, row)
                  }
                "
                class="table-button-green"
                :inTable="true"
              />
              <el-button
                v-else
                v-bind="btnsFilter(row)[0]"
                :class="
                  typeof btnsFilter(row)[0].class === 'function'
                    ? btnsFilter(row)[0].class(row)
                    : btnsFilter(row)[0].class
                    ? btnsFilter(row)[0].class
                    : 'table-button-green'
                "
                type="text"
                :disabled="
                  typeof btnsFilter(row)[0].disabled === 'function'
                    ? btnsFilter(row)[0].disabled(row)
                    : btnsFilter(row)[0].disabled
                "
                @click="btnsFilter(row)[0].click(row)"
              >
                {{ btnsFilter(row)[0].label }}
              </el-button>
              <el-dropdown>
                <el-button type="text" class="table-button-blue more-btn">
                  更多
                </el-button>
                <el-dropdown-menu slot="dropdown">
                  <template v-for="(button, index) in btnsFilter(row)">
                    <el-dropdown-item
                      v-if="index !== 0"
                      :key="index"
                      class="dropdown-btn"
                      :class="
                        typeof button.class === 'function'
                          ? button.class(row)
                          : button.class
                      "
                      :title="
                        typeof button.title === 'function'
                          ? button.title(row)
                          : button.title
                      "
                      v-bind="button"
                      :disabled="
                        typeof button.disabled === 'function'
                          ? button.disabled(row)
                          : button.disabled
                      "
                      @click.native="button.click(row)"
                    >
                      {{ button.label }}
                    </el-dropdown-item>
                  </template>
                </el-dropdown-menu>
              </el-dropdown>
            </template>
          </template>
        </el-table-column>
      </i-table>
      <el-pagination
        v-if="!paginationDisplay && paginationSlotDisplay"
        layout="slot"
        :page-size="paginationSlot.pageSize"
      >
        <button
          type="button"
          class="btn-prev"
          :disabled="paginationSlot.currentPage === 1"
          @click="() => handlePageSoltChange(paginationSlot.currentPage - 1)"
        >
          <i class="el-icon el-icon-arrow-left"></i>
        </button>
        <ul class="el-pager">
          <li class="number active">
            {{ paginationSlot.currentPage }}
          </li>
        </ul>
        <button
          type="button"
          class="btn-next"
          :disabled="
            tableData.list && tableData.list.length < paginationSlot.pageSize
          "
          @click="() => handlePageSoltChange(paginationSlot.currentPage + 1)"
        >
          <i class="el-icon el-icon-arrow-right"></i>
        </button>
      </el-pagination>
    </div>
  </div>
</template>
<script>
import { removeEmpty } from '@/utils'
import { tableComponentNames } from '@/utils/regComponent'
import SearchDatePicker from '@/components/SearchDatePicker'
import ExportButton from '@/components/ExportButton'
export default {
  components: { SearchDatePicker, ExportButton },
  props: {
    pageNameDisplay: {
      type: Boolean,
      default: true,
    },
    resetBtnDisplay: {
      type: Boolean,
      default: true,
    },
    paginationDisplay: {
      type: Boolean,
      default: true,
    },
    paginationSlotDisplay: {
      type: Boolean,
      default: false,
    },
    searchPath: {
      type: String,
      default: '',
    },
    tableBtns: {
      type: Array,
      default: () => [],
    },
    formItemsInline: {
      type: Array,
      default: () => [],
    },
    columns: {
      type: Array,
      default: () => [],
    },
    tableData: {
      type: Object,
      default: () => ({
        list: [],
        totalCount: 0,
      }),
    },
    form: {
      type: Object,
      default: () => {},
    },
    rules: {
      type: Object,
      default: () => {},
    },
  },
  data() {
    return {
      pageName: this.$route.meta.title,
      // displayOperationBtns: false,
      loading: false,
      layoutSpan: 24,
      labelWidth: 20,
      breakpoint: [
        [768, 1],
        [992, 2],
        [1200, 2],
        [1920, 3],
        [Infinity, 4],
      ],
      fold: true,
      id: 0,
      pagination: this.paginationDisplay
        ? {
            currentPage: 1,
            pageSize: 10,
          }
        : null,
      paginationSlot: this.paginationSlotDisplay
        ? {
            currentPage: 1,
            pageSize: 10,
          }
        : null,
    }
  },
  computed: {
    searchBtn() {
      return !this.searchPath || this.resourceSet.includes(this.searchPath)
    },
    maxPageCount() {
      return this.totalCount % this.pagination.pageSize
        ? this.totalCount -
            (this.totalCount % this.pagination.pageSize) /
              this.pagination.pageSize +
            1
        : this.totalCount / this.pagination.pageSize
    },
    handleColumns() {
      return this.columns
        .map((column) => {
          if (column.label === '操作') {
            return {
              slot: 'operationBtns',
              ...column,
            }
          } else {
            column.showOverflowTooltip = true
            return column
          }
        })
        .filter((column) => {
          return (
            !column.resourceId ||
            (column.label !== '操作' &&
              this.resourceSet.includes(column.resourceId)) ||
            (column.label === '操作' &&
              this.resourceSet.includes(column.resourceId) &&
              column.buttons.filter(
                (btn) =>
                  !btn.resourceId || this.resourceSet.includes(btn.resourceId)
              ).length)
          )
        })
    },
    handleFormItemInline() {
      return this.formItemsInline.filter((column) => {
        return (
          !column.resourceId || this.resourceSet.includes(column.resourceId)
        )
      })
    },
    operationBtns() {
      let column = this.columns.find((column) => {
        return column.label === '操作'
      })
      return column.buttons || []
    },
    resourceSet() {
      return this.$store.getters.resourceSet
    },
  },
  methods: {
    filterFormComponents(name) {
      return tableComponentNames.includes(name)
    },
    btnsFilter(row) {
      // if (
      //   this.operationBtns.filter((btn) => this.tableBtnsFilter(btn, row))
      //     .length !== 0
      // ) {
      //   this.displayOperationBtns = true
      // }

      return this.operationBtns.filter((btn) => this.tableBtnsFilter(btn, row))
    },
    tableBtnsFilter(btn, row) {
      const ifRenderFilter =
        btn.ifRender !== undefined
          ? typeof btn.ifRender === 'function'
            ? btn.ifRender(row)
            : btn.ifRender
          : true
      let permissionFilter = false
      if (btn.resourceId === undefined) {
        permissionFilter = true
      } else if (Array.isArray(btn.resourceId)) {
        btn.resourceId.forEach((id) => {
          if (this.resourceSet.includes(id)) {
            permissionFilter = true
          }
        })
      } else {
        if (this.resourceSet.includes(btn.resourceId)) {
          permissionFilter = true
        }
      }
      return ifRenderFilter && permissionFilter
    },
    handlePageChange({ type, val }) {
      this.pagination[type] = val
      type === 'currentPage' &&
        val > this.maxPageCount &&
        (this.pagination.currentPage = this.maxPageCount)
      type === 'pageSize' && (this.pagination.currentPage = 1)
      this.$emit('handleTableData', {
        ...this.pagination,
        ...removeEmpty(this.form),
      })
    },
    handlePageSoltChange(val) {
      this.paginationSlot.currentPage = val
      this.$emit('handleTableData', {
        ...this.paginationSlot,
        ...removeEmpty(this.form),
      })
    },
    formValidate() {
      let validate = true
      this.$refs.form.validate((valid) => {
        if (!valid) validate = false
      })

      return validate
    },
    handleTableData() {
      this.paginationDisplay ? (this.pagination.currentPage = 1) : null
      this.paginationSlotDisplay ? (this.paginationSlot.currentPage = 1) : null
      let data = Object.assign(
        {},
        removeEmpty(this.form),
        this.handleColumns.length &&
          (this.paginationDisplay
            ? JSON.parse(JSON.stringify(this.pagination))
            : this.paginationSlotDisplay
            ? JSON.parse(JSON.stringify(this.paginationSlot))
            : {})
      )
      this.$emit('handleTableData', data)
    },
    reset() {
      this.$emit('reset')
    },
    refreshTable() {
      this.paginationDisplay ? (this.pagination.currentPage = 1) : null
      this.paginationSlotDisplay ? (this.paginationSlot.currentPage = 1) : null
      this.handleTableData()
    },
    handleSelectionChange(rows) {
      this.$emit('multipleSelection', rows)
    },
    clearSelection() {
      this.$refs.iTable.$refs.table.clearSelection()
    },
    toggleRowSelection(row, selected) {
      this.$refs.iTable.$refs.table.toggleRowSelection(row, selected)
    },
    datePickerInputChange() {},
  },
  created() {
    this.handleTableData()
  },
}
</script>
<style lang="scss" scoped>
.btn-group-block {
  display: flex;
  .btn-group {
    margin-right: 10px;
    a {
      color: #005be5;
    }
    &:last-child {
      margin-right: 0px;
    }
  }
}
.unfold {
  transform: rotate(180deg);
}
.btn-seperator {
  margin: 0 5px;
  color: rgba(0, 0, 0, 0.06);
}
.table-search-wrapper {
  .form-wrapper {
    padding: 20px 0;
    background: #fff;
    .form-content {
      margin-left: -12px;
      display: flex;
      justify-content: space-between;
      align-items: flex-start;
    }
    .iform {
      flex: 1;
      margin-left: 16px;
    }
    .btn-wrapper {
      min-width: 130px;
      margin: 0 24px;
      .dash-control {
        cursor: pointer;
        margin: 0 5px;
        display: inline-block;
      }
    }
  }
  .table-dash {
    width: 100%;
    background: #fff;
    padding-top: 22px;
    // overflow: hidden;
    .search-header {
      height: 64px;
      line-height: 64px;
      padding: 0 16px;
      display: flex;
      justify-content: space-between;
      margin-top: -18px;
      .search-result-count {
        color: #b0bec5;
        font-size: 16px;
        margin-left: 20px;
        strong {
          color: #272727;
          margin: 0 10px;
        }
      }
    }
    .reset-style {
      height: 10px;
    }
    .table-wrapper {
      max-width: 100%;
      padding: 0 16px;
      clear: both;
      .cellClass {
        td:nth-child(1) {
          background-color: #f5f7fa;
        }
        td:nth-child(2) {
          background-color: #f5f7fa;
        }
      }
      .more-btn {
        cursor: pointer;
        margin-left: 10px;
      }
    }
  }
  .table-search__title {
    font-size: 16px;
    display: block;
    color: #2a2a2a;
    &::before {
      content: '';
      height: 14px;
      width: 4px;
      display: inline-block;
      background: #4c71f9;
      margin-left: 30px;
      margin-right: 14px;
    }
    &::after {
      content: '';
      background: #c9c9c9;
      height: 1px;
      width: 100%;
      margin: 18px 0 29px;
      display: block;
      transform: scaleY(0.5);
    }
  }
  .dialog-display {
    box-shadow: 2px 2px 6px 0px rgba(0, 0, 0, 0.1);
    border-radius: 10px;
    margin-bottom: 12px;
  }
}
.dropdown-btn {
  color: #2a2a2a;
  width: 100%;
  &:hover,
  &:focus,
  &:active {
    color: #4c71f9;
  }
}
.dropdown-btn.is-disabled {
  cursor: default;
  color: #bbb;
  pointer-events: none;
}

.search-result-count {
  color: #666666;
  font-size: 14px;
  margin-left: 20px;
  font-weight: 500;
  strong {
    color: #2878ff;
    margin: 0 4px;
  }
}

.pagination {
  margin-bottom: 20px;
}
</style>
